home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume35 / split.c / part01 next >
Encoding:
Text File  |  1993-03-04  |  6.7 KB  |  230 lines

  1. Newsgroups: comp.sources.misc
  2. From: ian@cs.man.ac.uk (Ian Cottam)
  3. Subject: v35i113:  split.c - A version of split.c for non-UNIX systems, Part01/01
  4. Message-ID: <1993Mar3.190752.20209@sparky.imd.sterling.com>
  5. X-Md4-Signature: b2294018c061498955362c4b9ae4e788
  6. Date: Wed, 3 Mar 1993 19:07:52 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ian@cs.man.ac.uk (Ian Cottam)
  10. Posting-number: Volume 35, Issue 113
  11. Archive-name: split.c/part01
  12. Environment: C
  13.  
  14. Here is a public domain version of the UNIX split command targeted at
  15. non-UNIX systems.
  16.  
  17. Ian Cottam, Room IT101, Department of Computer Science,
  18. University of Manchester, Oxford Road, Manchester, M13 9PL, U.K.
  19. TEL (+44) 61-275 6273 FAX (+44) 61-275-6236 EMAIL ian@cs.man.ac.uk
  20. -------------
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then feed it
  23. # into a shell via "sh file" or similar.  To overwrite existing files,
  24. # type "sh file -c".
  25. # Contents:  split.c
  26. # Wrapped by kent@sparky on Wed Mar  3 12:59:58 1993
  27. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  28. echo If this archive is complete, you will see the following message:
  29. echo '          "shar: End of archive 1 (of 1)."'
  30. if test -f 'split.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'split.c'\"
  32. else
  33.   echo shar: Extracting \"'split.c'\" \(4761 characters\)
  34.   sed "s/^X//" >'split.c' <<'END_OF_FILE'
  35. X/*
  36. X * Donated to the Public Domain by Ian D. Cottam on 93/2/19.
  37. X *       ********* NO WARRANTY OF ANY KIND ************
  38. X *
  39. X * This is IDC's reimplementation of UNIX split.
  40. X * I have never seen the AT&T original and have no idea how it works.
  41. X * This version is for PCs, and other non-UNIX machines, that
  42. X * have trouble editing big files.
  43. X *
  44. X * A conforming Standard C compiler, headers and library is required.
  45. X *
  46. X * 25 Feb.'93
  47. X */
  48. X
  49. X#include <stdio.h>
  50. X#include <string.h>
  51. X#include <stdlib.h>
  52. X#include <stdarg.h>
  53. X#include <limits.h>
  54. X
  55. X/* Change these if you like , but they are what the manual says! */
  56. Xenum {        DEFAULT_PIECE_SIZE           = 1000 };
  57. Xstatic char * const DEFAULT_FILE_PREFIX    = "x";
  58. Xstatic FILE * const DEFAULT_INPUT_FILE     = stdin;
  59. X
  60. X
  61. X/* here be prototypes of static/local functions */
  62. Xstatic void split(unsigned long int, FILE *, char *);
  63. Xstatic char *makenewfile(char *);
  64. Xstatic int  copyline(FILE*, FILE*, char*);
  65. Xstatic void AbortIf(int, char *fmt, ...);
  66. X
  67. Xstatic char *prog__name;        /* for use by AbortIf() */
  68. X
  69. X
  70. Xint main(int argc, char *argv[])
  71. X{
  72. X    unsigned long int piecesize= DEFAULT_PIECE_SIZE;
  73. X    FILE *infile= DEFAULT_INPUT_FILE;
  74. X    char *outfilename= DEFAULT_FILE_PREFIX;
  75. X    int status;            /* general return status code */
  76. X
  77. X    prog__name= argv[0];
  78. X
  79. X     /* check args */
  80. X    AbortIf(argc > 4, "usage: [-positivenumber] [infile[outfile]]");
  81. X    if (argc == 4)        /* -num infile outfilename */
  82. X    outfilename= argv[3];
  83. X    if (argc >= 3)        /* -num infile */
  84. X    if (strcmp(argv[2], "-") != 0) {
  85. X        infile= fopen(argv[2], "r");
  86. X        AbortIf(infile == NULL, "can't open: %s", argv[2]);
  87. X    }
  88. X    if (argc >= 2) {        /* -num */
  89. X    AbortIf(argv[1][0] != '-',
  90. X        "usage: [-positivenumber] [infile[outfile]]");
  91. X    status= sscanf(&argv[1][1], "%lu", &piecesize);
  92. X    AbortIf(status != 1 || piecesize == 0 || piecesize == ULONG_MAX,
  93. X        "usage: [-positivenumber] [infile[outfile]]");
  94. X    }
  95. X    split(piecesize, infile, outfilename);
  96. X    return 0;
  97. X}
  98. X
  99. X
  100. X/*
  101. X * This function follows main validation
  102. X * and does all the hard work
  103. X */
  104. Xstatic void split(unsigned long int piecesize, FILE *infile, char *outfilename)
  105. X{
  106. X    unsigned long int lno= 1;    /* 0 <= lno <= piecesize */
  107. X    int status;    /* general result status code */
  108. X    char *nextfilename= makenewfile(outfilename);
  109. X    FILE *outfile= fopen(nextfilename, "w");
  110. X
  111. X    AbortIf(outfile == NULL, "can't open output file: %s", nextfilename);
  112. X
  113. X    while (status= copyline(infile, outfile, nextfilename), status != EOF) {
  114. X    ++lno;
  115. X    if (lno > piecesize) {
  116. X        /* need to close current output, and open next */
  117. X        lno= 1;
  118. X        status= fclose(outfile);
  119. X        AbortIf(status == EOF,
  120. X            "error detected closing: %s", nextfilename);
  121. X        free(nextfilename);
  122. X        nextfilename= makenewfile(outfilename);
  123. X        outfile= fopen(nextfilename, "w");
  124. X        AbortIf(outfile == NULL,
  125. X            "can't open output file: %s", nextfilename);
  126. X    }
  127. X    }
  128. X    AbortIf(ferror(infile), "error detected reading input file");
  129. X    status= fclose(outfile);
  130. X    AbortIf(status == EOF, "error detected closing: %s", nextfilename);
  131. X    free(nextfilename);
  132. X}
  133. X
  134. X
  135. X/*
  136. X * Generates a new name of the form xab, xac, xad, etc.
  137. X */
  138. Xstatic char *makenewfile(char *prefix)
  139. X{
  140. X    static char *letters[]=
  141. X    {"", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
  142. X     "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
  143. X         "u", "v", "w", "x", "y", "z", NULL};
  144. X    static unsigned int first= 1, second= 0;
  145. X    char *filestring= malloc(strlen(prefix) + 3);
  146. X
  147. X    AbortIf(filestring == NULL, "out of space");
  148. X    ++second;
  149. X    if (letters[second] == NULL) {
  150. X    second= 1;
  151. X    ++first;
  152. X    AbortIf(letters[first] == NULL,
  153. X        "more than %saa-zz files needed, aborting", prefix);
  154. X
  155. X    }
  156. X    return
  157. X      strcat(strcat(strcpy(filestring,prefix),letters[first]),letters[second]);
  158. X}
  159. X
  160. X
  161. X/*
  162. X * Copies next line from infile to outfile
  163. X * EOF returned on input error or genuine EOF.
  164. X * Aborts if can't write.
  165. X */
  166. Xstatic int copyline(FILE *infile, FILE *outfile, char *nextfilename)
  167. X{
  168. X    int ch, status;
  169. X
  170. X    while (ch= getc(infile), ch != '\n' && ch != EOF) {
  171. X        status= putc(ch, outfile);
  172. X        AbortIf(status == EOF, "error writing: %s", nextfilename);
  173. X    }
  174. X    if (ch == '\n') {
  175. X        status= putc('\n', outfile);
  176. X        AbortIf(status == EOF, "error writing: %s", nextfilename);
  177. X        /* check to see if now at EOF */
  178. X        ch= getc(infile);
  179. X        if (ch != EOF) {
  180. X            status= ungetc(ch, infile);
  181. X            AbortIf(status == EOF, "input file buffer problem");
  182. X            ch= '\n';
  183. X        }
  184. X    }
  185. X    return ch;
  186. X
  187. X}
  188. X
  189. X
  190. X/*
  191. X * Error handler (uses prog__name)
  192. X */
  193. Xstatic void AbortIf(int failure, char *fmt, ...)
  194. X{
  195. X    va_list args;
  196. X    
  197. X    if (failure) {
  198. X      va_start(args, fmt);
  199. X      fprintf(stderr, "%s: ", prog__name ? prog__name : "<application>");
  200. X      vfprintf(stderr, fmt, args);
  201. X      fprintf(stderr, "\n");
  202. X      va_end(args);
  203. X      exit(EXIT_FAILURE);
  204. X    }
  205. X}
  206. X
  207. END_OF_FILE
  208.   if test 4761 -ne `wc -c <'split.c'`; then
  209.     echo shar: \"'split.c'\" unpacked with wrong size!
  210.   fi
  211.   # end of 'split.c'
  212. fi
  213. echo shar: End of archive 1 \(of 1\).
  214. cp /dev/null ark1isdone
  215. MISSING=""
  216. for I in 1 ; do
  217.     if test ! -f ark${I}isdone ; then
  218.     MISSING="${MISSING} ${I}"
  219.     fi
  220. done
  221. if test "${MISSING}" = "" ; then
  222.     echo You have the archive.
  223.     rm -f ark[1-9]isdone
  224. else
  225.     echo You still must unpack the following archives:
  226.     echo "        " ${MISSING}
  227. fi
  228. exit 0
  229. exit 0 # Just in case...
  230.